package ru.chaykin.viewobject.texture;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

import ru.chaykin.primitives.Circle;

import android.graphics.Bitmap;
import android.opengl.GLUtils;

public abstract class TextureFactory {
	private static int[] texturesId = null;
	private static Bitmap[] texturesMaps = null;
	
	private static FloatBuffer texCoord; //Условные координаты текстуры (масштабировать можно ее с их помощью)  
	
	private static ShortBuffer indices; //Порядок следования вершин...
	
	public static void genTexIds(int n, GL10 gl) {
		texturesId = new int[n];
		texturesMaps = new Bitmap[n];
		gl.glGenTextures(n, texturesId, 0);
		initTexBuffs();
	}
	
	public static Texture genTexture(Circle circle, int id, int midIndex, Bitmap bm, float[] rect) {
		if (texturesId != null && id >=0 && id < texturesId.length) {
			texturesMaps[id] = bm;
			return new Texture(circle, texturesId[id], midIndex, rect);
		}
		return null;
	}
	
	public static void bindTextureIfNeeded(GL10 gl, int id) {
		if (id >=0 && id < texturesId.length && texturesMaps[id] != null) {
			gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesId[id]);
			
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); // Create Nearest Filtered Texture
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
	
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
			gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
			
			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texturesMaps[id], 0);
			texturesMaps[id] = null;
		}
	}
	
	private static void initTexBuffs() { 
		ByteBuffer byteBuf = ByteBuffer.allocateDirect(8 * Float.SIZE / 8); //8 это 4 точки по 2 координаты
		byteBuf.order(ByteOrder.nativeOrder());
		texCoord = byteBuf.asFloatBuffer();
		texCoord.put(0);
		texCoord.put(1);
		
		texCoord.put(1);
		texCoord.put(1);
		
		texCoord.put(0);
		texCoord.put(0);
		
		texCoord.put(1);
		texCoord.put(0);
		texCoord.position(0);
		
		ByteBuffer ibb = ByteBuffer.allocateDirect(6 * Short.SIZE / 8); 
		ibb.order(ByteOrder.nativeOrder());
		indices = ibb.asShortBuffer();
		indices.put((short) 0);
		indices.put((short) 1);
		indices.put((short) 2);
		indices.put((short) 1);
		indices.put((short) 3);
		indices.put((short) 2);
		indices.position(0);
	}
	
	public static FloatBuffer getTexCoord() {
		return texCoord;
	}
	
	public static ShortBuffer getIndices() {
		return indices;
	}
}
